/*
 * Created on Feb 12, 2008
 */
package maxygen;

import java.io.BufferedWriter;

/**
 * The <code>RawWriter</code> should deal with the layout of the plain text
 * document (e.g., number of chars per line)
 * 
 * @author martinrobinson
 */
class RawWriter
{
    BufferedWriter o;
    int count = 0;
    int carWidth;
    int tabWidth;
    boolean lastWriteOK = true;
    
    RawWriter(BufferedWriter o_)
    {
        this(o_,80,4); // defaults: carriage width 80, tab width 4 spaces
    }
    
    RawWriter(BufferedWriter o_, int c, int t)
    {
        o = o_;
        carWidth = c >= 4 ? c : 4;
        tabWidth = t >= 1 ? t : 1;
    }
    
    public void write(String s) throws Exception
    {
        o.write(s);
        
        /* perhaps need to split the strings on \n chars first?
        s = replaceTabs(s);
        
        int length = s.length();
        
        if(count+length > carWidth)
            breakString(s);
        else {
            lastWriteOK = true;
            o.write(s);
            
            count += length;
            if(count > carWidth) {
                newLine();
            }
        }
        */
        
    }
    
    private void breakString(String s) throws Exception
    {
        int remain = carWidth - count;
        
        while(remain > 0 && !isStrongBreak(s.charAt(remain)) ) 
            remain--;
        
        if(remain <= 0) {
            newLine();
            if(lastWriteOK) {
                lastWriteOK = false;
                write(s);
            } else {
                doBreakString(s, carWidth-count); // arbitrary break
            }
        }
        
        doBreakString(s, remain);
    }
    
    private void doBreakString(String s, int index) throws Exception
    {
        String left = s.substring(0, index);
        String right = s.substring(index);
        write(left);
        newLine();
        write(right);
    }
    
    private void cr() throws Exception
    {
        count = 0;
        o.write("\n");
    }
    
    private void newLine() throws Exception
    {
        cr();
        write("\t");
    }
    
    private boolean isStrongBreak(char c)
    {
        switch(c) {
        case ' ':
        case ',':
        case ':':
        case ')':
        case ']':
        case '}':
            return true;
        default:
            return false;
        }
    }
    
    public void close() throws Exception
    {
        o.close();
    }
    
    private String replaceTabs(String s)
    {
        String tab = "";
        
        for(int i = 0; i < tabWidth; i++) {
            tab += " ";
        }
        return s.replaceAll("\t", tab);
    }
    
}
